"""应用注册管理模块
负责发现、注册和管理所有应用模块，处理路由挂载等公共逻辑
"""
import os
import importlib
from typing import Dict, List, Any, Optional
from fastapi import FastAPI, APIRouter
from pkg.logger import get_logger
logger = get_logger()

class AppRegistry:
    """应用注册表
    用于管理所有已注册的应用模块，提供应用发现、路由挂载等功能
    """

    def __init__(self):
        self._apps: Dict[str, Any] = {}
        self._app_routers: Dict[str, APIRouter] = {}
        self._loaded = False

    def discover_apps(self) -> List[str]:
        """发现可用的应用
        通过扫描apps目录下的文件夹，自动发现可用的应用
        """
        apps_dir = os.path.dirname(__file__)
        app_names = []

        # 遍历apps目录下的所有目录
        for item in os.listdir(apps_dir):
            # 排除非目录和以_开头的目录
            if not os.path.isdir(os.path.join(apps_dir, item)) or item.startswith('_'):
                continue

            # 检查是否有router.py文件，判断是否为有效应用
            router_path = os.path.join(apps_dir, item, 'router.py')
            if os.path.exists(router_path):
                app_names.append(item)

        return app_names

    def register_app(self, app_name: str) -> bool:
        """注册应用
        :param app_name: 应用名称
        :return: 是否注册成功
        """
        if app_name in self._apps:
            logger.info(f"应用 {app_name} 已经注册过了")
            return False

        try:
            logger.info(f"正在注册应用: {app_name}")
            # 尝试导入应用的router模块
            router_module = importlib.import_module(f"apps.{app_name}.router")
            logger.info(f"成功导入模块: apps.{app_name}.router")

            # 获取应用路由器
            if hasattr(router_module, 'router'):
                app_router = getattr(router_module, 'router')
                api_prefix = getattr(router_module, 'API_PREFIX', f'/{app_name}')

                # logger.info(f"应用 {app_name} 路由器包含 {len(app_router.routes)} 个路由")

                self._app_routers[app_name] = app_router
                self._apps[app_name] = {
                    'name': app_name,
                    'router': app_router,
                    'prefix': api_prefix
                }
                return True
            else:
                logger.error(f"应用 {app_name} 的router模块中没有找到router属性")
                return False
        except ImportError as e:
            logger.error(f"导入应用 {app_name} 失败: {e}")
            return False

    def load_all_apps(self) -> None:
        if self._loaded:
            return

        app_names = self.discover_apps()
        for app_name in app_names:
            self.register_app(app_name)

        self._loaded = True

    def mount_app_routes(self, app: FastAPI) -> None:
        """挂载所有应用的路由
        :param app: FastAPI实例
        """
        # 导入全局API前缀
        from pkg.core.urls import API_PREFIX as GLOBAL_API_PREFIX

        for app_name, app_info in self._apps.items():
            prefix = app_info['prefix']
            router = app_info['router']
            # 将应用路由挂载到主应用
            # 结合全局API前缀和应用自身前缀
            full_prefix = f"{GLOBAL_API_PREFIX}{prefix}"
            app.include_router(router, prefix=full_prefix, tags=[app_name])
            # print(f"已挂载应用 {app_name} 路由到前缀: {full_prefix}")


    @property
    def apps(self) -> Dict[str, Any]:
        """获取所有已注册的应用"""
        return self._apps

    def get_app_router(self, app_name: str) -> Optional[APIRouter]:
        """获取指定应用的路由器
        :param app_name: 应用名称
        :return: 应用路由器
        """
        return self._app_routers.get(app_name)

    def discover_models(self) -> List[str]:
        """发现所有已注册应用的模型路径
        动态扫描所有已注册应用中的models模块，返回所有模型的导入路径
        :return: 模型导入路径列表
        """
        if not self._loaded:
            self.load_all_apps()

        model_paths = ["aerich.models"]  # 始终包含aerich模型

        app_names = self.discover_apps()

        for app_name in app_names:
            # 检查应用是否有models目录
            app_path = os.path.join(os.path.dirname(__file__), app_name)
            models_dir = os.path.join(app_path, "models")

            if os.path.exists(models_dir) and os.path.isdir(models_dir):
                # 遍历models目录下的所有.py文件
                for file_name in os.listdir(models_dir):
                    if file_name.endswith(".py") and not file_name.startswith("_"):
                        # 去掉.py后缀
                        model_name = file_name[:-3]
                        model_path = f"apps.{app_name}.models.{model_name}"
                        # logger.info(f"发现模型: {model_path}")
                        model_paths.append(model_path)

        return model_paths


# 全局应用注册表实例
app_registry = AppRegistry()
